
#include "tools/variant.h"

#if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW__)
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Weffc++"
//    #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif


namespace tools{
    namespace variant_detail{

        namespace {
            typedef V::Str Str;
        }

//---------------------------------------------------------------------------------------------
        void IteratorBase::SetBeg() { mCur = mBeg; }
        void IteratorBase::SetEnd() { mCur = mEnd; }

        bool IteratorBase::IsBeg()const
        {
            return !mCur.Empty() && *mCur == *mBeg;
        }
        bool IteratorBase::IsEnd()const { return *mCur == *mEnd; }

        bool IteratorBase::Empty()const { return mCur.Empty() ||  IsEnd(); }

        bool IteratorBase::operator==(const IteratorBase& rhs)const
        {
            const size_t empty_this  = Empty()?     1: 0;
            const size_t empty_other = rhs.Empty()? 1: 0;
            if(empty_this + empty_other == 2)
                return true;
            if(empty_this != empty_other)
                return false;

            return *mCur==*rhs.mCur;
        }
        bool IteratorBase::operator!=(const IteratorBase& rhs)const{ return !operator==(rhs); }

        void IteratorBase::operator=(const IteratorBase& rhs)
        {
            mBeg = rhs.mBeg;
            mCur = rhs.mCur;
            mEnd = rhs.mEnd;
        }

        const Str& IteratorBase::GetKey()const
        {
            const bool ERROR_GETKEY_FROM_EMPTY_ITERATOR = Empty();
            assert(!ERROR_GETKEY_FROM_EMPTY_ITERATOR);
            if(ERROR_GETKEY_FROM_EMPTY_ITERATOR)
                throw ::std::logic_error("ERROR_GETKEY_FROM_EMPTY_ITERATOR");

            return mCur->GetKey();
        }
        const Variant& IteratorBase::GetVariant()const
        {
            const bool ERROR_GETVARIANT_FROM_EMPTY_ITERATOR = Empty();
            assert(!ERROR_GETVARIANT_FROM_EMPTY_ITERATOR);
            if(ERROR_GETVARIANT_FROM_EMPTY_ITERATOR)
                throw ::std::logic_error("ERROR_GETVARIANT_FROM_EMPTY_ITERATOR");

            return mCur->GetVariant();
        }

        void IteratorBase::Right() { mCur->Right(); }
        void IteratorBase::Left()  { mCur->Left();  }

        const Variant* IteratorBase::operator->()const
        {
            return &GetVariant();
        }
        const Variant& IteratorBase::operator*()const
        {
            const bool ERROR_DEREFERENCING_EMPTY_ITERATOR = Empty();
            assert(!ERROR_DEREFERENCING_EMPTY_ITERATOR);
            if(ERROR_DEREFERENCING_EMPTY_ITERATOR)
                throw ::std::logic_error("ERROR_DEREFERENCING_EMPTY_ITERATOR");

            return mCur->GetVariant();
        }

//---------------------------------------------------------------------------------------------
        Iterator::Iterator(Variant& v, const bool beg)
        {
            this->mBeg = v.GetHelper()->GetIterator( v, true  );
            this->mCur = v.GetHelper()->GetIterator( v, beg  );
            this->mEnd = v.GetHelper()->GetIterator( v, false );
        }
        Iterator::Iterator(Variant& v,const eSTARTUP, const bool beg)
        {
            this->mBeg = v.GetHelper()->GetPrimitiveIterator( v, true  );
            this->mCur = v.GetHelper()->GetPrimitiveIterator( v, beg  );
            this->mEnd = v.GetHelper()->GetPrimitiveIterator( v, false );
        }
//---------------------------------------------------------------------------------------------
        ConstIterator::ConstIterator(const Variant& v, const bool beg)
        {
            this->mBeg = v.GetHelper()->GetConstIterator( v, true  );
            this->mCur = v.GetHelper()->GetConstIterator( v, beg   );
            this->mEnd = v.GetHelper()->GetConstIterator( v, false );
        }
        ConstIterator::ConstIterator(Variant& v, const bool beg)
        {
            this->mBeg = v.GetHelper()->GetConstIterator( v, true  );
            this->mCur = v.GetHelper()->GetConstIterator( v, beg   );
            this->mEnd = v.GetHelper()->GetConstIterator( v, false );
        }
        ConstIterator::ConstIterator(Variant& v,const eSTARTUP, const bool beg)
        {
            this->mBeg = v.GetHelper()->GetPrimitiveConstIterator( v, true  );
            this->mCur = v.GetHelper()->GetPrimitiveConstIterator( v, beg  );
            this->mEnd = v.GetHelper()->GetPrimitiveConstIterator( v, false );
        }
        ConstIterator::ConstIterator(const Variant& v,const eSTARTUP, const bool beg)
        {
            this->mBeg = v.GetHelper()->GetPrimitiveConstIterator( v, true  );
            this->mCur = v.GetHelper()->GetPrimitiveConstIterator( v, beg  );
            this->mEnd = v.GetHelper()->GetPrimitiveConstIterator( v, false );
        }
//---------------------------------------------------------------------------------------------
        ReverseIterator::ReverseIterator(Variant& v, const bool beg)
        {
            this->mBeg = v.GetHelper()->GetReverseIterator( v, true  );
            this->mCur = v.GetHelper()->GetReverseIterator( v, beg   );
            this->mEnd = v.GetHelper()->GetReverseIterator( v, false );
        }
        ReverseIterator::ReverseIterator(Variant& v,const eSTARTUP, const bool beg)
        {
            this->mBeg = v.GetHelper()->GetPrimitiveReverseIterator( v, true  );
            this->mCur = v.GetHelper()->GetPrimitiveReverseIterator( v, beg  );
            this->mEnd = v.GetHelper()->GetPrimitiveReverseIterator( v, false );
        }
//---------------------------------------------------------------------------------------------
        ConstReverseIterator::ConstReverseIterator(const Variant& v, const bool beg)
        {
            this->mBeg = v.GetHelper()->GetConstReverseIterator( v, true  );
            this->mCur = v.GetHelper()->GetConstReverseIterator( v, beg   );
            this->mEnd = v.GetHelper()->GetConstReverseIterator( v, false );
        }

        ConstReverseIterator::ConstReverseIterator(Variant& v, const bool beg)
        {
            this->mBeg = v.GetHelper()->GetConstReverseIterator( v, true  );
            this->mCur = v.GetHelper()->GetConstReverseIterator( v, beg   );
            this->mEnd = v.GetHelper()->GetConstReverseIterator( v, false );
        }
        ConstReverseIterator::ConstReverseIterator(Variant& v,const eSTARTUP, const bool beg)
        {
            this->mBeg = v.GetHelper()->GetPrimitiveConstReverseIterator( v, true  );
            this->mCur = v.GetHelper()->GetPrimitiveConstReverseIterator( v, beg  );
            this->mEnd = v.GetHelper()->GetPrimitiveConstReverseIterator( v, false );
        }
        ConstReverseIterator::ConstReverseIterator(const Variant& v,const eSTARTUP, const bool beg)
        {
            this->mBeg = v.GetHelper()->GetPrimitiveConstReverseIterator( v, true  );
            this->mCur = v.GetHelper()->GetPrimitiveConstReverseIterator( v, beg  );
            this->mEnd = v.GetHelper()->GetPrimitiveConstReverseIterator( v, false );
        }
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------



    }//namespace variant_detail
}//namespace tools

#if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW__)
    #pragma GCC diagnostic pop
#endif
